#pragma once

#include <string>
#include <vector>
#include <ctime>
#include "KinectWrapper.h"
#include "DataReader.h"
#include "opencv2/myopencv.hpp"

using namespace std;
using namespace cv;

// const int DEVICE_TYPE_OPENCV_COLOR = 0;
// const int DEVICE_TYPE_KINECT_DEPTH = 1;
// const int DEVICE_TYPE_KINECT_COLOR = 2;
// const int DEVICE_TYPE_KINECT_DEPTH_COLOR = 3;
// const int DEVICE_TYPE_FILE_COLOR = 4;
// const int DEVICE_TYPE_FILE_DEPTH = 5;
// const int DEVICE_TYPE_FILE_GRAY = 6;
enum EOFCAPTURE_DEVICE_TYPE {
	UNKNOWN,
	DEVICE_TYPE_OPENCV_COLOR,
	DEVICE_TYPE_KINECT_DEPTH,
	DEVICE_TYPE_KINECT_COLOR,
	DEVICE_TYPE_KINECT_DEPTH_COLOR,
	DEVICE_TYPE_FILE_COLOR,
	DEVICE_TYPE_FILE_DEPTH,
	DEVICE_TYPE_FILE_GRAY
};

class FrameMeta {
public:
	EOFCAPTURE_DEVICE_TYPE type;
	int fromDeviceId;
	long timestamp;

	inline FrameMeta(EOFCAPTURE_DEVICE_TYPE t = UNKNOWN, int id = -1, long ts = -1) {
		type = t;
		fromDeviceId = id;
		timestamp = (ts == -1) ? clock() : ts;
	}
};


class EOFCapture
{
private:
	vector<EOFCAPTURE_DEVICE_TYPE> mDeviceTypes;
	vector<void*> mDevicePtrs;
	vector<bool> mCreateByMe;

	CvMat *depthRes;
	CvMat *colorRes;
	CvMat *mappedRes;
	CvMat *grayRes;

	CvMat *grayFromFileBuf;
	CvMat *mappedFromFileBuf;
	CvMat *colorFromFileBuf;

public:
	vector<Mat> mFrames;
	vector<FrameMeta> mFrameMeta;

	int width;
	int height;

public:
	EOFCapture(int usePredefineId = -1);

	int SetCapture(void *cap, EOFCAPTURE_DEVICE_TYPE type);
	int SetCapture(VideoCapture *cap);
	int SetCapture(KinectDepthColorWrapper *cap);
	int SetCapture(KinectDepthWrapper *cap);

	bool SelectFrame(EOFCAPTURE_DEVICE_TYPE type, Mat& img);
	bool SelectFrame(int deviceId, Mat& img);
	bool Retrieve(int id = -1);

	~EOFCapture(void);
};
